﻿using System;
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class UIEventListener : EventTrigger
{
    private bool isLockClick = false;
    private float waitTime = 0;

    /// <summary>
    /// 与界面有交互时触发
    /// </summary>
    public static Action onOperate;

    public Action aniClickDown = null; //动画按下
    public Action aniClickUp = null; //动画抬起
    public Action soundClick = null; //点击音效

    public Action<GameObject, PointerEventData> onClickDown = null;
    public Action<GameObject, PointerEventData> onClickUp = null;
    public Action<GameObject, PointerEventData> onClick = null;
    public Action<GameObject, PointerEventData> onEnter = null;
    public Action<GameObject, PointerEventData> onExit = null;
    public Action<GameObject, PointerEventData> onInitializePotentialDrag = null;
    public Action<GameObject, PointerEventData> onBeginDrag = null;
    public Action<GameObject, PointerEventData> onDrag = null;
    public Action<GameObject, PointerEventData> onEndDrag = null;
    public Action<GameObject, PointerEventData> onDrop = null;
    public Action<GameObject, BaseEventData> onSelect = null;
    public Action<GameObject, BaseEventData> onUpdateSelected = null;
    public Action<GameObject, BaseEventData> onDeselect = null;
    public Action<GameObject, BaseEventData> onSubmit = null;
    public Action<GameObject, BaseEventData> onCancel = null;
    public Action<GameObject, PointerEventData> onScroll = null;
    public Action<GameObject, AxisEventData> onMove = null;

    public ScrollRect parentScroolRect = null;

    private Coroutine pointerClickCoroutine = null;

    /// <summary>
    /// 设定点击锁定
    /// </summary>
    /// <param name="_bool">true：上锁  false：解锁</param>
    public void SetClickLock(bool _bool)
    {
        isLockClick = _bool;
    }

    public void SetWaitTime(float time)
    {
        waitTime = time;
    }

    /// <summary>
    /// 按钮防连点禁用
    /// </summary>
    /// <returns></returns>
    IEnumerator StartWaitTime()
    {
        SetClickLock(true);
        yield return new WaitForSeconds(waitTime);
        SetClickLock(false);
    }

    public override void OnPointerDown(PointerEventData eventData)
    {
        if (isLockClick) return;
        if (onClickDown != null)
        {
            onOperate?.Invoke();
            onClickDown.Invoke(gameObject, eventData);
        }

        if (aniClickDown != null) aniClickDown.Invoke();
    }

    public override void OnPointerUp(PointerEventData eventData)
    {
        if (isLockClick) return;
        if (onClickUp != null) onClickUp.Invoke(gameObject, eventData);
        if (aniClickUp != null) aniClickUp.Invoke();
    }

    public override void OnPointerClick(PointerEventData eventData)
    {
        if (isLockClick) return;
        if (onClick != null)
        {
            onOperate?.Invoke();
            onClick.Invoke(gameObject, eventData);
        }

        if (soundClick != null) soundClick.Invoke();

        if (gameObject.activeInHierarchy)
        {
            if (waitTime > 0)
            {
                if (pointerClickCoroutine != null)
                    StopCoroutine(pointerClickCoroutine);
                pointerClickCoroutine = StartCoroutine(StartWaitTime());
            }
        }
    }

    public override void OnPointerEnter(PointerEventData eventData)
    {
        if (onEnter != null) onEnter.Invoke(gameObject, eventData);
    }

    public override void OnPointerExit(PointerEventData eventData)
    {
        if (onExit != null) onExit.Invoke(gameObject, eventData);
    }

    public override void OnInitializePotentialDrag(PointerEventData eventData)
    {
        if (onInitializePotentialDrag != null) onInitializePotentialDrag.Invoke(gameObject, eventData);
    }

    public override void OnBeginDrag(PointerEventData eventData)
    {
        if (onBeginDrag != null)
        {
            onOperate?.Invoke();
            onBeginDrag.Invoke(gameObject, eventData);
        }

        if (parentScroolRect != null) parentScroolRect.OnBeginDrag(eventData);
    }

    public override void OnDrag(PointerEventData eventData)
    {
        if (onDrag != null)
        {
            onOperate?.Invoke();
            onDrag.Invoke(gameObject, eventData);
        }

        if (parentScroolRect != null) parentScroolRect.OnDrag(eventData);
    }

    public override void OnEndDrag(PointerEventData eventData)
    {
        if (onEndDrag != null)
        {
            onOperate?.Invoke();
            onEndDrag.Invoke(gameObject, eventData);
        }

        if (parentScroolRect != null) parentScroolRect.OnEndDrag(eventData);
    }

    public override void OnDrop(PointerEventData eventData)
    {
        if (onDrop != null) onDrop.Invoke(gameObject, eventData);
    }

    public override void OnSelect(BaseEventData eventData)
    {
        if (onSelect != null) onSelect.Invoke(gameObject, eventData);
    }

    public override void OnUpdateSelected(BaseEventData eventData)
    {
        if (onUpdateSelected != null) onUpdateSelected.Invoke(gameObject, eventData);
    }

    public override void OnDeselect(BaseEventData eventData)
    {
        if (onDeselect != null) onDeselect.Invoke(gameObject, eventData);
    }

    public override void OnSubmit(BaseEventData eventData)
    {
        if (onSubmit != null) onSubmit.Invoke(gameObject, eventData);
    }

    public override void OnCancel(BaseEventData eventData)
    {
        if (onCancel != null) onCancel.Invoke(gameObject, eventData);
    }

    public override void OnScroll(PointerEventData eventData)
    {
        if (onScroll != null)
        {
            onOperate?.Invoke();
            onScroll.Invoke(gameObject, eventData);
        }
    }

    public override void OnMove(AxisEventData eventData)
    {
        if (onMove != null) onMove.Invoke(gameObject, eventData);
    }

    public void SetScrollRectDrag(ScrollRect sc)
    {
        parentScroolRect = sc;
    }

    public void SetScrollRectDrag(GameObject go)
    {
        ScrollRect sc = go.GetComponent<ScrollRect>();
        if (sc != null) parentScroolRect = sc;
    }

    public static UIEventListener Get(GameObject go)
    {
        UIEventListener listener = go.GetComponent<UIEventListener>();
        if (listener == null) listener = go.AddComponent<UIEventListener>();
        return listener;
    }

    private void OnDisable()
    {
        if (pointerClickCoroutine != null)
        {
            StopCoroutine(pointerClickCoroutine);
            SetClickLock(false);
            pointerClickCoroutine = null;
        }
    }
}